package com.bsg.upm.service;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.cache.DefinitionMetricClassCache;
import com.bsg.upm.constant.MonitorCommonMap;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.entity.DefinitionMetricClassEntity;
import com.bsg.upm.entity.DefinitionMetricEntity;
import com.bsg.upm.entity.HostEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;

@Service
public class MonitorHostConfigService extends BaseService {
	@Resource
	private DefinitionMetricClassCache definitionMetricClassCache;

	public RespJson enableMetricClass(String siteId, String metricClass, ArrayList<String> hostIds)
			throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("name", getRelateIds(siteId, hostIds));

		String urlPattern = "/{0}/hosts/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metricClass);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorHostConfigService:enableMetricClass fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson disableMetricClass(String siteId, String metricClass, ArrayList<String> hostIds)
			throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("name", getRelateIds(siteId, hostIds));

		String urlPattern = "/{0}/hosts/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metricClass);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorHostConfigService:disableMetricClass fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public String getSiteIdByHostId(String hostid) throws APIException {
		HostEntity hostEntity = hostDao.get(hostid);

		if (hostEntity == null) {
			throw new APIException(hostid + ":don't find the host");
		}

		return hostEntity.getCluster().getArea().getSite().getId();

	}

	public RespJson enableEvent(String siteId, String metric, ArrayList<String> hostIds) throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("name", getRelateIds(siteId, hostIds));

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.HOST_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		String urlPattern = "/{0}/hosts/event/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorHostConfigService:enableEvent fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson disableEvent(String siteId, String metric, ArrayList<String> hostIds) throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("name", getRelateIds(siteId, hostIds));

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.HOST_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		String urlPattern = "/{0}/hosts/event/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorHostConfigService:disableEvent fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson enableEventLevel(String siteId, String metric, String level, ArrayList<String> hostIds)
			throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("name", getRelateIds(siteId, hostIds));
		paramJson.put("level", level);

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.HOST_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		String urlPattern = "/{0}/hosts/level/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorHostConfigService:enableEventLevel fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson disableEventLevel(String siteId, String metric, String level, ArrayList<String> hostIds)
			throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("name", getRelateIds(siteId, hostIds));
		paramJson.put("level", level);
		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.HOST_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		String urlPattern = "/{0}/hosts/level/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("MonitorHostConfigService:enableEventLevel fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson updateEvent(String siteId,ArrayList<String>  hosts,String metric, String level, String start, String end)
			throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("level", level);
		paramJson.put("start", start);
		paramJson.put("end", end);
		paramJson.put("hosts", hosts);

		String relateMetric = definitionMetricCache.getMetric(MonitorCommonMap.HOST_TYPE, metric);
		if (relateMetric == null) {
			throw new APIException(metric + ":don't find the metric");
		}

		String urlPattern = "/{0}/hosts/level/{1}";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, relateMetric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("updateEvent fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson updateMetricClassIntervalTime(String siteId, String metricClass, ArrayList<String> hostIds,
			int intervaltime) throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("name", getRelateIds(siteId, hostIds));

		String urlPattern = "/{0}/hosts/{1}";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metricClass);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("updateMetricClassIntervalTime fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson listHostEvent(String hostId) throws APIException {
		JSONArray retJsonArray = new JSONArray();
		HostEntity hostEntity = hostDao.get(hostId);
		if (hostEntity == null) {
			return RespJsonFactory.buildOK(retJsonArray);
		}

		String siteId = hostEntity.getCluster().getArea().getSite().getId();
		String hostRelateId = hostEntity.getRelateId();

		JSONArray eventConfigs = getHostEventFromHS(siteId, hostRelateId);
		List<DefinitionMetricEntity> dfMetrics = definitionMetricCache.listDfMetricFromCache();
		for (Object config : eventConfigs) {
			retJsonArray.add(getEventShowObj(dfMetrics, (JSONObject) config));
		}

		return RespJsonFactory.buildOK(retJsonArray);
	}

	public RespJson listHostMetricClass(String hostId) throws APIException {
		JSONArray retJsonArray = new JSONArray();
		HostEntity hostEntity = hostDao.get(hostId);
		if (hostEntity == null) {
			return RespJsonFactory.buildOK(retJsonArray);
		}

		String siteId = hostEntity.getCluster().getArea().getSite().getId();
		String hostRelateId = hostEntity.getRelateId();

		JSONArray metricConfigs = getHostMetricClassFromHS(siteId, hostRelateId);
		List<DefinitionMetricClassEntity> dfMetrics = definitionMetricClassCache.listDfMetricClassFromCache();

		for (Object config : metricConfigs) {
			retJsonArray.add(getMetricClassShowObject(dfMetrics, (JSONObject) config));
		}

		return RespJsonFactory.buildOK(retJsonArray);
	}
    public  JSONObject getMetricClassShowObject(List<DefinitionMetricClassEntity> dfMetrics, JSONObject metricClass) {
		JSONObject mectricClassObj = new JSONObject();

		mectricClassObj.put("name", null);
		mectricClassObj.put("description", null);
		mectricClassObj.put("metric_class", null);
		mectricClassObj.put("interval_time", null);
		mectricClassObj.put("enable", null);
		mectricClassObj.put("history", null);

		if (metricClass == null) {
			return mectricClassObj;
		}
		
		mectricClassObj.put("metric_class", metricClass.getString("metric_class"));
		mectricClassObj.put("interval_time", metricClass.getString("interval_time"));
		mectricClassObj.put("enable", metricClass.getBoolean("enable"));
		mectricClassObj.put("history", metricClass.getBoolean("history"));

		if (dfMetrics != null) {
			for (DefinitionMetricClassEntity definitionMetricClass : dfMetrics) {
				if (mectricClassObj.getString("metric_class").equals(definitionMetricClass.getMetricClass())) {
					mectricClassObj.put("name", definitionMetricClass.getName());
					mectricClassObj.put("description", definitionMetricClass.getDescription());
					break;
				}

			}

		}

		return mectricClassObj;
	}

    public JSONObject getEventShowObj(List<DefinitionMetricEntity> dfMetrics, JSONObject event) {
		JSONObject eventObj = new JSONObject();
		
		eventObj.put("relate_metric", event.getString("metric"));
		eventObj.put("start", event.getString("start"));
		eventObj.put("end", event.getString("end"));
		eventObj.put("event_level", event.getString("level"));
		eventObj.put("event_enable", event.getBoolean("enable"));
		eventObj.put("alarm_enable", event.getBoolean("alarm_enable"));
		eventObj.put("event_counter", event.getInteger("counter"));
		
		for (DefinitionMetricEntity definitionMetricEntity:dfMetrics){
			if (definitionMetricEntity.getMetric().equals(event.getString("metric"))){
				
				eventObj.put("metric", definitionMetricEntity.getName());
				
				String metricName = definitionMetricEntity.getDescription();			 
				eventObj.put("metric_name", metricName);
				
				String levelName = MonitorCommonMap.getLevelName(event.getString("level"));
				eventObj.put("level_name", levelName);

				String eventName = metricName + ":" + levelName + "类";
				eventObj.put("event_name", eventName);

				String eventDescription = metricName + "的" + levelName + "等级";
				eventObj.put("event_description", eventDescription);
				
				break;
			}
		}
		

		return eventObj;
	}

	private JSONArray getHostEventFromHS(String siteId, String hostRelateId) throws APIException {

		String urlPattern = "/{0}/event/{1}?metric_object_type=host";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, hostRelateId);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("getHostMetricClassFromHS fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}
		
		JSONObject datas =   (JSONObject)httpRespJson.getData();
		if (datas.isEmpty()){
			return new JSONArray(); 
		}
		
		return datas.getJSONArray("event_configs");


 
	}

	private JSONArray getHostMetricClassFromHS(String siteId, String hostRelateId) throws APIException {

		String urlPattern = "/{0}/metricclass/{1}?metric_object_type=host";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, hostRelateId);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("getHostMetricClassFromHS fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}
		
		JSONObject datas =   (JSONObject)httpRespJson.getData();
		if (datas.isEmpty()){
			return new JSONArray(); 
		}
		
		return datas.getJSONArray("metric_configs");


	}

	private JSONArray getRelateIds(String siteId, ArrayList<String> hostIds) {
		JSONArray hostRelateIds = new JSONArray();
		List<HostEntity> hostEntities = hostDao.list(null);
		for (String hostid : hostIds) {
			if (hostid == null) {
				continue;
			}
			
			boolean find = false;
			for (HostEntity host : hostEntities) {
				if (host.getId().equals(hostid)) {
					hostRelateIds.add(host.getRelateId());
					find = true;
					break;
				}
			}
			
			if (!find) {
				logger.warn((String) hostid + ":don't find the hostrelateid from db");
			}

		}

		return hostRelateIds;
	}

	private boolean isHttp2XX(int status) {
		if (status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED) {
			return true;
		}
		return false;
	}

}